package com.wutu.nbyjk8.safe;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @Author : Liuts
 * @Desc : 对参数、响应做正则校验，防止SQL注入、XSS攻击等
 * @create 2023/12/27 11:00
 */
@Slf4j
public class NbyjInterceptor implements HandlerInterceptor {

    //"<", ">", "=", "..", "/*", "*/", "?", "'"
    //       , "$", "%", "*", "|"
    private static final String[] SAFE_STRINGS = {
            "<", ">", "=", "..", "/*", "*/", "?", "'"
            , "$", "%", "*", "|"
    };//非法字符串
    private final static List<String> excludes = Arrays.asList(new String[]{
            //"/xxx/xxx"
            "/fuse/draw/add",
            "/fuse/view/add",
            "/add"});//不需要过滤的url

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        if (!excludes.contains(requestURI)) {
            //检查url参数
            Map<String, String[]> parameterMap = request.getParameterMap();
            for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
                String[] values = entry.getValue();
                for (String value : values) {
                    if (!isSafe(value)) {
                        log.error("{}访问请求检测到非法字符串{}", requestURI, value);
                        return false;
                    }
                }
            }
            //检查参数body
            /*if (request instanceof RequestWrapper) {
                RequestWrapper req = (RequestWrapper) request;
                String body = req.getBodyString();
                if (!isSafe(body)) {
                    log.error("{}访问请求检测到非法字符串{}", requestURI, body);
                    return false;
                }
            }*/
        }

        return true;
    }

    /**
     * @param str
     * @Desc: 检查字符串中是否包含非法字符串
     * @return: boolean
     * @Author: lts
     * @Date: 2023/12/27 14:01
     */
    private boolean isSafe(String str) {
        for (String s : SAFE_STRINGS) {
            if (str.contains(s)) {
                return false;
            }
        }
        return true;
    }

    public static String inputStreamToString(InputStream inputStream) throws IOException {
        StringBuilder sb = new StringBuilder();
        byte[] buffer = new byte[4096];
        int bytesRead = -1;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            sb.append(new String(buffer, 0, bytesRead));
        }
        return sb.toString();
    }

}
